
package com.feib.soeasy.action;

import java.io.StringReader;
import java.util.Calendar;

import com.feib.soeasy.model.Group;
import com.feib.soeasy.model.PaymentCanceledReason;
import com.feib.soeasy.model.RealAccount;
import com.feib.soeasy.pagination.PaginatedList;
import com.feib.soeasy.security.SoeasyInvocationSecurityMetadataSourceService;
import com.feib.soeasy.service.FormatDefinitionService;
import com.feib.soeasy.service.GroupService;
import com.feib.soeasy.service.PaymentCanceledReasonService;
import com.feib.soeasy.service.RealAccountService;
import com.feib.soeasy.service.RoleService;
import com.feib.soeasy.service.UploadFileService;
import com.feib.soeasy.service.UserService;
import com.feib.soeasy.util.UserUtil;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.action.StreamingResolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.LocalizableError;
import net.sourceforge.stripes.validation.Validate;
import net.sourceforge.stripes.validation.ValidateNestedProperties;
import net.sourceforge.stripes.validation.ValidationErrors;


/**
 * @title (#)Soez9007ActionBean.java<br>
 * @description 帳單業者資料設定<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @2011/1/31 create by Jimmy Liu<br>
 */
public class Soez9007ActionBean extends BaseActionBean {

    private static final String DEFAULT_JSP = "/WEB-INF/views/soez9007/soez9007.jsp";
    
    /**
     * 帳單上傳記錄查詢結果畫面
     */
    private static final String AJAX_QUERY_JSP = "/WEB-INF/views/soez9007/soez9007List.jsp";
    
    private static final String AJAX_EDIT_JSP = "/WEB-INF/views/soez9007/soez9007Edit.jsp";
    
    private static final String AJAX_EDIT_REAL_ACCOUNT_JSP = "/WEB-INF/views/soez9007/soez9007EditRealAccount.jsp";
    
    private static final String AJAX_EDIT_PAYMENT_WRITEOFF_JSP = "/WEB-INF/views/soez9007/soez9007EditPaymentCanceledReason.jsp";
    
    /**
     * 業者代號查詢畫面
     */
    private static final String AJAX_QUERY_GROUP_JSP = "/WEB-INF/views/soez9007/groupPopUpList.jsp";

    
    /**
     * 查詢條件
     */
    private RealAccount qryRealAccount;
    
    /**
     * 查詢結果
     */
    private PaginatedList<Group> queryResult;
    
    @ValidateNestedProperties({
        @Validate(field="groupPk", required=true, on={"toAjaxEditGroup"}  )
    })
    private Group editGroup;
    
    
    
    /**
     * 帳單業者查詢條件
     */
    private Group qryGroup;
    /**
     * 帳單業者查詢結果
     */
    private String groupNo;
    private String queryId;
   
    private PaginatedList<Group> queryGroupResult;
    
      
    
    /**
     * 查詢結果
     */
    private PaginatedList<RealAccount> queryRealAccount;
    
    /**
     * 查詢結果
     */
    private PaginatedList<PaymentCanceledReason> queryPaymentCanceledReason;
    
    private RealAccount editRealAccount;
    
    private PaymentCanceledReason paymentCanceledReason; 

    @SpringBean("paymentCanceledReasonService")
    private PaymentCanceledReasonService paymentCanceledReasonService;
    
    @SpringBean("groupService")
    private GroupService groupService;

    @SpringBean("uploadFileService")
    private UploadFileService uploadFileService;

    @SpringBean("roleService")
    private RoleService roleService;
    
    @SpringBean("userService")
    private UserService userService;

    @SpringBean("formatDefinitionService")
    private FormatDefinitionService formatDefinitionService;

    @SpringBean("realAccountService")
    private RealAccountService realAccountService;
    

    @SpringBean("soeasySecurityMetadataSource")
    private SoeasyInvocationSecurityMetadataSourceService invocationSecurityMetadataSourceService;

    @DontBind
    @DefaultHandler
    public Resolution doDefault()
    {
        logger.debug("Enter doDefault mehtod.");
        return new ForwardResolution(DEFAULT_JSP); 
    }
    
    /**
     * 查詢
     * @return
     */
    public Resolution doAjaxQuery()
    {
        logger.debug("Enter doAjaxQuery mehtod.");
        if (null == qryRealAccount)
            qryRealAccount = new RealAccount();
        
        Group qryGroup = qryRealAccount.getGroup();
        if (null == qryGroup)
            qryGroup = new Group();
        
        if (null == queryResult)
            queryResult = new PaginatedList<Group>();
        queryResult = groupService.queryPaginationByGroupvirtualAccountNo(qryGroup, qryRealAccount.getAccountNo(), queryResult);
        return new ForwardResolution(AJAX_QUERY_JSP); 
    }
    
    public Resolution toAjaxAddGroup()
    {
        return new ForwardResolution(AJAX_EDIT_JSP); 
    }
    
    public Resolution toAjaxEditRealAccount()
    {
        RealAccount realAccount = new RealAccount();
        realAccount.setGroup(this.editGroup);
        this.queryRealAccount = realAccountService.queryByRealAccount(realAccount, this.queryRealAccount);
        return new ForwardResolution(AJAX_EDIT_REAL_ACCOUNT_JSP); 
    }
    
    public Resolution toAjaxEditGroup()
    {
        this.editGroup = this.groupService.queryByPk(this.editGroup.getGroupPk());
        return new ForwardResolution(AJAX_EDIT_JSP); 
    }
    
    /**
     * 銷帳代碼設定
     * @return
     */
    public Resolution toAjaxEditPaymentCanceled(){
    	logger.debug("Enter toAjaxEditPaymentCanceled Method");
    	PaymentCanceledReason tempPaymentCanceledReason = new PaymentCanceledReason();
    	tempPaymentCanceledReason.setGroup(this.editGroup);
    	this.queryPaymentCanceledReason = paymentCanceledReasonService.queryByRealAccount(tempPaymentCanceledReason, this.queryPaymentCanceledReason);
    	return new ForwardResolution(AJAX_EDIT_PAYMENT_WRITEOFF_JSP);
    }
    
    /**
     * 保存銷帳代碼設定
     * @return
     */
    public Resolution doAjaxSavePaymentCanceledReason()
    {
    	/* 進入保存銷帳代碼設定方法,記錄LOG信息 */
        logger.debug("Enter doAjaxSavePaymentCanceledReason method.");

        StringBuffer msg = new StringBuffer();        
        try {
        	/* 檢查從WEB頁面獲取使用者鍵入的銷帳代碼設定 */
        	if(this.paymentCanceledReason != null && this.paymentCanceledReason.getCanceledNo() != null){
        		/* 當銷帳代碼為999時,與系統設定的需求衝突,故不做新增操作 */
        		if( !"999".equals(this.paymentCanceledReason.getCanceledNo())){
		        	/* 當沒有檢測到銷帳代碼在資料庫的Pk時,為新增操作 */
		        	if(this.paymentCanceledReason.getPaymentCanceledReasonPk() == null)
		            {
		        		this.paymentCanceledReason.setPaymentCanceledReasonPk(null);
		        		/* 呼叫新增服務 */
		                this.paymentCanceledReasonService.addPaymentCanceledReason(this.paymentCanceledReason);
		                /* 新增成功後的提示信息 */
		                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveResultPaymentCancelCode' value='1'/>");  
		            }
		        	/* 修改銷帳代碼 */
		            else
		            {
		            	/* 根據銷帳代碼設定Pk查詢欲修改的銷帳代碼的詳細資料 */
		            	PaymentCanceledReason paymentCanceledReasonInDb = this.paymentCanceledReasonService.queryByPk(this.paymentCanceledReason.getPaymentCanceledReasonPk());
		            	/* 當銷帳代碼沒有使用，可以更新 */
		            	if(!"Y".equals(paymentCanceledReasonInDb.getIsUsed())){
		            		/* 更新為使用者鍵入的銷帳代碼設定資料 */
			            	paymentCanceledReasonInDb.setCanceledNo(this.paymentCanceledReason.getCanceledNo());
			            	paymentCanceledReasonInDb.setCancelReason(this.paymentCanceledReason.getCancelReason());
			            	/* 更新銷帳代碼設定 */                
			                this.paymentCanceledReason = this.paymentCanceledReasonService.save(paymentCanceledReasonInDb);
			                /* 更新成功提示信息 */
			                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveResultPaymentCancelCode' value='1'/>");
		            	}
		            	/* 如果已經被使用,則無法更新相關資料 */
		            	else{
		            		msg.append("該註銷代碼已經被使用,儲存失敗!").append("<input type='hidden' id='doAjaxSaveResultPaymentCancelCode' value='1'/>");
		            	}
		            }
        		}
        		/* 銷帳代碼為999時的錯誤提示信息 */
        		else{
        			msg.append("儲存失敗，999為系統預訂代碼!").append("<input type='hidden' id='doAjaxSaveResultPaymentCancelCode' value='1'/>");
        		}
        	}
        }
        /* 異常處理 */
        catch (Exception e) {
            logger.error("",e);
            msg.append("儲存失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    /**
     * 刪除銷帳代碼設定
     * @return
     */
    public Resolution doAjaxDeletePaymentCanceledReason()
    {
    	/* 進入刪除方法,記錄LOG */
        logger.debug("Enter doAjaxDeletePaymentCanceledReason method.");

        StringBuffer msg = new StringBuffer();
        /* 嘗試刪除銷帳代碼 */
        try {
        	/* 查詢欲刪除的銷帳代碼詳細資料 */
        	PaymentCanceledReason paymentCanceledReasonInDb = this.paymentCanceledReasonService.queryByPk(this.paymentCanceledReason.getPaymentCanceledReasonPk());
        	/* 當銷帳代碼沒有使用，可以刪除 */
        	if(!"Y".equals(paymentCanceledReasonInDb.getIsUsed())){
        		/* 呼叫刪除服務 */
	        	this.paymentCanceledReasonService.deletePaymentCanceledReason(this.paymentCanceledReason);
	            msg.append("刪除成功").append("<input type='hidden' id='doAjaxDeleteResultPaymentCancelCode' value='1'/>");
        	}
        	/* 如果已經被使用,則無法刪除 */
        	else{
        		msg.append("該註銷代碼已經被使用,刪除失敗!").append("<input type='hidden' id='doAjaxDeleteResultPaymentCancelCode' value='1'/>");
        	}
        }
        /* 異常處理 */
        catch (Exception e) {
            logger.error("",e);
            msg.append("刪除失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    
    /**
     * 儲存業者資訊(新增/修改)
     * 
     * @return
     */
    public Resolution doAjaxSaveGroup()
    {

        logger.debug("Enter doAjaxSaveGroup method.");

        StringBuffer msg = new StringBuffer();
        
        try {
            if(this.editGroup.getGroupPk() == null)
            {
                if (groupService.isDuplicateGroupNo(this.editGroup.getGroupNo()))
                {
                    msg.append("業者代號 ").append(editGroup.getGroupNo()).append(" 已有使用.");
                }
                else
                {
                    this.editGroup.setGroupPk(null);
                    this.editGroup.setCreatedBy(UserUtil.getUserName());
                    this.editGroup.setCreatedDate(Calendar.getInstance().getTime());
                    this.editGroup.setUpdatedBy(UserUtil.getUserName());
                    this.editGroup.setUpdatedDate(Calendar.getInstance().getTime());
                    this.editGroup.setAtmAmount(new Long(0));
                    this.editGroup.setBankAmount(new Long(0));
                    this.editGroup.setChainstoreAmount(new Long(0));
                    this.editGroup.setPostAmount(new Long(0));
                    this.editGroup.setOtherAmount(new Long(0));
                    this.editGroup.setRemittanceAmount(new Long(0));
                    this.editGroup.setPostLevel1(new Long(5));
                    this.editGroup.setPostLevel2(new Long(10));
                    this.editGroup.setPostLevel3(new Long(15));
                    this.editGroup.setSelfAmount(new Long(0));
                    this.editGroup = this.groupService.addGroup(editGroup);
                    msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveGroupResultCode' value='1'/>");
                    msg.append("<br/>請繼續設定實體帳戶");
                    msg.append("<input type='hidden' id='continueEditRealAccount' value='1'/>");
                    msg.append("<input type='hidden' id='doAjaxSavegroupPk' value='").append(this.editGroup.getGroupPk()).append("'/>");


                }

            }
            else
            {
                Group groupInDb = this.groupService.queryByPk(this.editGroup.getGroupPk());
                groupInDb.setGroupName(this.editGroup.getGroupName());
                groupInDb.setMainBank(this.editGroup.getMainBank());
                groupInDb.setGroupAddress(this.editGroup.getGroupAddress());
                groupInDb.setGroupNote(this.editGroup.getGroupNote());
                groupInDb.setPostAcct(this.editGroup.getPostAcct());
                groupInDb.setContactName(this.editGroup.getContactName());
                groupInDb.setContactCellNo(this.editGroup.getContactCellNo());
                groupInDb.setContactEmail(this.editGroup.getContactEmail());
                groupInDb.setContactTelNo(this.editGroup.getContactTelNo());
                groupInDb.setAchEdiid(this.editGroup.getAchEdiid());/* 20120521  增加 ACH代碼  */                
                this.editGroup = this.groupService.save(groupInDb);
                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveGroupResultCode' value='1'/>");
                
            }
            
            invocationSecurityMetadataSourceService.setToReload();
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("儲存失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    public Resolution doDeleteGroup()
    {
        logger.debug("Enter doDeleteGroup method.");

        StringBuffer msg = new StringBuffer();
        
        try {
            if (formatDefinitionService.countFormatDefinitionByGroup(this.editGroup) > 0)
            {
                msg.append("已有設定上傳格式，無法刪除");
            }
            else if (uploadFileService.countUploadFileByGroup(this.editGroup) > 0)
            {
                msg.append("已有上傳檔案紀錄，無法刪除");
            }
            else if (userService.countUserByGroupExcludeAdmin(this.editGroup) > 0)
            {
                msg.append("帳單業者已經有新增使用者，無法刪除");
            }
            else if (roleService.countRoleByGroupExcludeAdmin(this.editGroup) > 0)
            {
                msg.append("帳單業者已經有設定角色，無法刪除");
            }
            else
            {
                this.groupService.deleteGroup(this.editGroup);
                msg.append("刪除成功").append("<input type='hidden' id='doAjaxDeleteGroupResultCode' value='1'/>");

                invocationSecurityMetadataSourceService.loadResourceDefine();
            }
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("刪除失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }

    public Resolution doAjaxSaveRealAccount()
    {
        logger.debug("Enter doAjaxSaveRealAccount method.");

        StringBuffer msg = new StringBuffer();
        
        try {
            if(this.editRealAccount.getRealAccountPk() == null)
            {
                this.editRealAccount.setRealAccountPk(null);
                this.realAccountService.addRealAccount(this.editRealAccount);

                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveResultRealAccountCode' value='1'/>");  
            }
            else
            {
                RealAccount realAccountInDb = this.realAccountService.queryByPk(this.editRealAccount.getRealAccountPk());
                realAccountInDb.setAccountNo(this.editRealAccount.getAccountNo());
                realAccountInDb.setVirtualAccountNo(this.editRealAccount.getVirtualAccountNo());
                realAccountInDb.setPartnerNo(this.editRealAccount.getPartnerNo());
                this.editRealAccount = this.realAccountService.save(realAccountInDb);
                msg.append("儲存成功").append("<input type='hidden' id='doAjaxSaveResultRealAccountCode' value='1'/>");
            }
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("儲存失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    public Resolution doAjaxDeleteRealAccount()
    {
        logger.debug("Enter doAjaxDeleteRealAccount method.");

        StringBuffer msg = new StringBuffer();
        
        try {
            this.realAccountService.deleteRealAccount(this.editRealAccount);
            msg.append("刪除成功").append("<input type='hidden' id='doAjaxDeleteResultRealAccountCode' value='1'/>");
        }
        catch (Exception e) {
            logger.error("",e);
            msg.append("刪除失敗");
        }
        StreamingResolution resolution = new StreamingResolution("text/html", new StringReader(msg.toString()));
        resolution.setCharacterEncoding("UTF-8");
        return resolution;
    }
    
    
    
    
    
    /**
     * 帳單業者查詢
     * @return
     */
    public Resolution doAjaxQueryGroups()
    {
        logger.debug("Enter doAjaxQueryGroups mehtod.");
        try {
            //USER未輸入查詢條件，所以查詢物件會是NULL(查詢物件不可為NULL)
            if (null == qryGroup)
                qryGroup = new Group();


            //呼叫服務查詢
            queryGroupResult = groupService.queryByGroupExcludeBank(qryGroup, queryGroupResult);
        }
        catch (Exception e) {
            logger.error("帳單明細資料下載-帳單業者查詢錯誤(Soez9007ActionBean.doAjaxQueryGroups):", e);

            // 轉換錯誤訊息
            ValidationErrors errors = new ValidationErrors();
            errors.addGlobalError(new LocalizableError("doAjaxQuery.exception") );
            getContext().setValidationErrors(errors);
            // 回傳 錯誤 HTML fragments
            return super.errorsToHtmlStreams(errors);
        }

        return new ForwardResolution(AJAX_QUERY_GROUP_JSP);
    }
    
    
    
    /**
     * @return the qryRealAccount
     */
    public RealAccount getQryRealAccount() {
        return qryRealAccount;
    }

    
    /**
     * @param qryRealAccount the qryRealAccount to set
     */
    public void setQryRealAccount(RealAccount qryRealAccount) {
        this.qryRealAccount = qryRealAccount;
    }

    
    /**
     * @return the queryResult
     */
    public PaginatedList<Group> getQueryResult() {
        return queryResult;
    }

    
    /**
     * @param queryResult the queryResult to set
     */
    public void setQueryResult(PaginatedList<Group> queryResult) {
        this.queryResult = queryResult;
    }

    
    /**
     * @return the editGroup
     */
    public Group getEditGroup() {
        return editGroup;
    }

    
    /**
     * @param editGroup the editGroup to set
     */
    public void setEditGroup(Group editGroup) {
        this.editGroup = editGroup;
    }

    
    /**
     * @return the queryRealAccount
     */
    public PaginatedList<RealAccount> getQueryRealAccount() {
        return queryRealAccount;
    }

    
    /**
     * @param queryRealAccount the queryRealAccount to set
     */
    public void setQueryRealAccount(PaginatedList<RealAccount> queryRealAccount) {
        this.queryRealAccount = queryRealAccount;
    }

    
    /**
     * @return the editRealAccount
     */
    public RealAccount getEditRealAccount() {
        return editRealAccount;
    }

    
    /**
     * @param editRealAccount the editRealAccount to set
     */
    public void setEditRealAccount(RealAccount editRealAccount) {
        this.editRealAccount = editRealAccount;
    }

    /**
     * @param qryGroup the qryGroup to set
     */
    public void setQryGroup(Group qryGroup) {
        this.qryGroup = qryGroup;
    }

    /**
     * @return the qryGroup
     */
    public Group getQryGroup() {
        return qryGroup;
    }

    /**
     * @param groupNo the groupNo to set
     */
    public void setGroupNo(String groupNo) {
        this.groupNo = groupNo;
    }

    /**
     * @return the groupNo
     */
    public String getGroupNo() {
        return groupNo;
    }

    /**
     * @param queryId the queryId to set
     */
    public void setQueryId(String queryId) {
        this.queryId = queryId;
    }

    /**
     * @return the queryId
     */
    public String getQueryId() {
        return queryId;
    }

    /**
     * @param queryGroupResult the queryGroupResult to set
     */
    public void setQueryGroupResult(PaginatedList<Group> queryGroupResult) {
        this.queryGroupResult = queryGroupResult;
    }

    /**
     * @return the queryGroupResult
     */
    public PaginatedList<Group> getQueryGroupResult() {
        return queryGroupResult;
    }

	/**
	 * @return the queryPaymentCanceledReason
	 */
	public PaginatedList<PaymentCanceledReason> getQueryPaymentCanceledReason() {
		return queryPaymentCanceledReason;
	}

	/**
	 * @param queryPaymentCanceledReason the queryPaymentCanceledReason to set
	 */
	public void setQueryPaymentCanceledReason(
			PaginatedList<PaymentCanceledReason> queryPaymentCanceledReason) {
		this.queryPaymentCanceledReason = queryPaymentCanceledReason;
	}

	/**
	 * @return the paymentCanceledReason
	 */
	public PaymentCanceledReason getPaymentCanceledReason() {
		return paymentCanceledReason;
	}

	/**
	 * @param paymentCanceledReason the paymentCanceledReason to set
	 */
	public void setPaymentCanceledReason(PaymentCanceledReason paymentCanceledReason) {
		this.paymentCanceledReason = paymentCanceledReason;
	}

}
